#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <time.h>
#include <unistd.h>
#include "inc/mq.h"
#include <sys/prctl.h>


// 生产者线程函数
void* producer(void* arg) {
    prctl(PR_SET_NAME, "producer");
    MessageQueue* mq = (MessageQueue*)arg;
    char buffer[256];
    int count = 0;
    
    // 使用线程安全的随机数生成
    unsigned int seed = (unsigned int)(time(NULL) ^ pthread_self());
    
    while (count < 10000) {
        snprintf(buffer, sizeof(buffer), "Message %d from producer %lu", 
                 count++, (unsigned long)pthread_self());
        mq_enqueue(mq, buffer);
        usleep(rand_r(&seed) % 100000); // 使用线程安全的随机数
    }
    
    return NULL;
}

// 消费者线程函数
void* consumer(void* arg) {
    prctl(PR_SET_NAME, "consumer");
    MessageQueue* mq = (MessageQueue*)arg;
    int count = 0;
    
    // 使用线程安全的随机数生成
    unsigned int seed = (unsigned int)(time(NULL) ^ pthread_self());
    
    while (1) {
        Message* msg = mq_dequeue(mq);
        if (msg) {
            free(msg);
            count++;
        }
        usleep(rand_r(&seed) % 150000); // 使用线程安全的随机数
    }
    
    return NULL;
}

int main() {
    // 创建消息队列，容量为5
    MessageQueue* mq = mq_init(100);
    if (!mq) {
        fprintf(stderr, "Failed to initialize message queue\n");
        return EXIT_FAILURE;
    }
    
    pthread_t prod_thread1, prod_thread2;
    pthread_t cons_thread1, cons_thread2;
    int ret = EXIT_SUCCESS;
    
    // 创建生产者线程
    if (pthread_create(&prod_thread1, NULL, producer, mq) != 0) {
        perror("Failed to create producer thread 1");
        ret = EXIT_FAILURE;
        goto cleanup;
    }
    
    if (pthread_create(&prod_thread2, NULL, producer, mq) != 0) {
        perror("Failed to create producer thread 2");
        ret = EXIT_FAILURE;
        pthread_cancel(prod_thread1);
        goto cleanup;
    }
    
    // 创建消费者线程
    if (pthread_create(&cons_thread1, NULL, consumer, mq) != 0) {
        perror("Failed to create consumer thread 1");
        ret = EXIT_FAILURE;
        pthread_cancel(prod_thread1);
        pthread_cancel(prod_thread2);
        goto cleanup;
    }
    
    if (pthread_create(&cons_thread2, NULL, consumer, mq) != 0) {
        perror("Failed to create consumer thread 2");
        ret = EXIT_FAILURE;
        pthread_cancel(prod_thread1);
        pthread_cancel(prod_thread2);
        pthread_cancel(cons_thread1);
        goto cleanup;
    }
    
    // 等待线程结束
    pthread_join(prod_thread1, NULL);
    pthread_join(prod_thread2, NULL);
    pthread_join(cons_thread1, NULL);
    pthread_join(cons_thread2, NULL);

cleanup:
    // 销毁消息队列
    mq_destroy(mq);
    
    if (ret == EXIT_SUCCESS) {
        printf("Message queue demo completed successfully.\n");
    } else {
        fprintf(stderr, "Message queue demo failed.\n");
    }
    
    return ret;
}
